use crate::compose::{CallBox, Composer, FError};

pub fn get_file_content(file_path: &str) -> Result<String, FError> {
    let content = std::fs::read_to_string(file_path).map_err(|e| FError::IoError(e.to_string()))?;
    Ok(content) 
}

pub fn write_file_content(file_path: &str, content: &str) -> Result<(), FError> {
    std::fs::write(file_path, content).map_err(|e| FError::IoError(e.to_string()))?;
    Ok(())
}

pub fn get_dir_file_paths(dir_path: &str) -> Result<Vec<String>, FError> {
    let paths = walkdir::WalkDir::new(dir_path)
    .into_iter()
    .filter_map(|e| e.ok())
    .filter(|e| e.file_type().is_file())
    .map(|e| {
         let full_path = e.path().to_str().unwrap().to_string();
         // 从绝对路径中移除input_dir前缀，得到相对路径
         full_path.strip_prefix(dir_path)
             .unwrap_or(&full_path)
             .trim_start_matches('/')
             .trim_start_matches('\\')
             .to_string()
     })
    .collect::<Vec<String>>();
    Ok(paths) 
}

pub fn make_fetcher() -> CallBox<'static, String, String> {
    let client = reqwest::Client::new();

    Composer::from_fn(move |url| {
        let client = client.clone();
        async move {
            let resp = client.get(url).send()
                .await
                .map_err(|e| FError::HttpError(e.to_string()))?;
            let body = resp.text()
                .await
                .map_err(|e| FError::ParseError(e.to_string()))?;
            Ok(body)
        }
    })
}

pub fn make_html2md_handler() -> CallBox<'static, String, String> {
    Composer::from_fn(move |html: String| {
        async move {
            let markdown = html2md::parse_html(&html);
            Ok(markdown)
        }
    })
}
